﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Mysoft.MyCM.Web.Controllers
{
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	public class MHandleExceptionFilterAttribute : HandleErrorAttribute, IExceptionFilter
	{
		/// <summary>
		/// Mysoft.Fix 异常过滤器
		/// </summary>
		/// <param name="requestType"></param>
		public MHandleExceptionFilterAttribute(MRequestType requestType)
		{
			this.RequestType = requestType;
		}

		public override void OnException(ExceptionContext filterContext)
		{
			var param = MRequestParam.GetRequestParam(filterContext.Controller.ViewData);
			Type exType = filterContext.Exception.GetType();
			var info = new MHandleExceptionInfo();
			info.Exception = filterContext.Exception;
			info.WindowLocation = param.CurrentWindowLocation;
			if (exType.Equals(typeof(System.AggregateException)))
			{
				// webapi异常
				info.ExceptionType = MHandleExceptionType.InvalidApi;
				info.Message = "中央服务器好像打酱油去了，请稍后再试...";
				LogException(param, filterContext.Exception);
			}
			else if (exType.Equals(typeof(MInvalidRequestParamException)))
			{
				// 请求参数异常
				info.ExceptionType = MHandleExceptionType.InvalidRequest;
				info.Message = ((MInvalidRequestParamException)info.Exception).Message;
				LogException(param, filterContext.Exception);
			}
			else if (exType.Equals(typeof(M.MException)))
			{
				// 业务异常
				info.ExceptionType = MHandleExceptionType.InvalidRequest;
				info.Message = ((M.MException)info.Exception).Message;
			}
			else
			{
				// 其他未处理异常，记录日志
				info.ExceptionType = MHandleExceptionType.Fatal;
				info.Message = info.Exception.Message;
				LogException(param, filterContext.Exception);
			}

			filterContext.ExceptionHandled = true;
			switch (this.RequestType)
			{
				case MRequestType.Ajax:
					filterContext.Result = new JsonResult()
					{
						Data = new M.Web.AjaxHttpResult()
						{
							Result = false,
							UserData = info.Message
						}
					};
					break;
				default:
					filterContext.Result = new ViewResult
					{
						ViewName = this.View,
						MasterName = this.Master,
						ViewData = new ViewDataDictionary<MHandleExceptionInfo>(info),
						TempData = filterContext.Controller.TempData
					};
					break;
			}
			//base.OnException(filterContext);
		}

		protected void LogException(MRequestParam requestParam, Exception exception)
		{
			Business.CMLogger.Log
				(
				requestParam.RequestIndentity,
				requestParam.LogonUser == null ? "unknown" : requestParam.LogonUser.Code,
				requestParam.RequestRemoteIP,
				string.Format("{0}.{1}", requestParam.Controller, requestParam.Action),
				requestParam.CurrentWindowLocation,
				exception.ToString(),
				M.MExceptionLevel.Stop
				);
		}

		/// <summary>
		/// 页面请求类型
		/// </summary>
		public MRequestType RequestType { get; private set; }
	}
}